import json
import uuid
import time

from fastapi import WebSocket


# 连接管理器
class ConnectionManager:
    def __init__(self, db=None):
        self.active_connections = {}
        self.last_activate = {}
        self.db = db

    async def to_connect(self, websocket: WebSocket, username: str, mac_addr: str):
        """
        建立socket连接
        """
        await websocket.accept()
        socket_id = str(uuid.uuid4())
        self.active_connections[socket_id] = websocket
        self.last_activate[socket_id] = int(time.time())
        return socket_id

    async def connect(self, websocket: WebSocket, username: str, mac_addr: str):
        socket_id = ""
        # 先检查用户连接是否已经存在
        user_info = self.db.get_one("User", {"mac_addr": mac_addr})
        if user_info:
            # 更新ws socket client
            if user_info.get("socket_id") in self.active_connections:
                self.active_connections.pop(user_info["socket_id"], None)

            socket_id = await self.to_connect(websocket, username, mac_addr)
            # 更新用户信息
            self.db.upsert_one(
                "User",
                {"name": username, "mac_addr": mac_addr, "socket_id": socket_id, "status": "online"},
                {"mac_addr": mac_addr},
            )
            # 发送通知
            await self.send2client(
                json.dumps(
                    {
                        "category": "connected",
                        "context": socket_id,
                    },
                    ensure_ascii=False,
                ),
                websocket,
            )

        else:
            socket_id = await self.to_connect(websocket, username, mac_addr)
            # 更新用户信息
            self.db.upsert_one(
                "User",
                {"name": username, "mac_addr": mac_addr, "socket_id": socket_id, "status": "online"},
                {"mac_addr": mac_addr},
            )
            # 发送通知
            await self.send2client(
                json.dumps(
                    {
                        "category": "connected",
                        "context": socket_id,
                    },
                    ensure_ascii=False,
                ),
                websocket,
            )

        return socket_id

    async def disconnect(self, socket_id: str):
        # 先获取websocket连接（如果存在）
        websocket = self.active_connections.pop(socket_id, None)
        self.last_activate.pop(socket_id, None)
        # 如果连接存在且未关闭，则尝试关闭
        if websocket:
            try:
                await websocket.close()
            except Exception:
                # 忽略关闭时可能发生的错误
                pass
        # 更新用户表
        self.db.update_one("User", {"socket_id": socket_id, "status": "offline"}, {"socket_id": socket_id})

    async def send2client(self, message: str, websocket: WebSocket):
        try:
            await websocket.send_text(message)
        except Exception as e:
            # 忽略发送消息时可能发生的错误
            print(f"Error sending message: {str(e)}")


    async def update_last_activate(self, socket_id: str):
        self.last_activate[socket_id] = int(time.time())
